/*
 * PhoenixSingleton.h
 *
 *  Created on: 2014. 6. 19.
 *      Author: jjaehuny
 */

#ifndef FRAMEWORK_PHOENIXSINGLETON_H_
#define FRAMEWORK_PHOENIXSINGLETON_H_

namespace Framework { namespace Util {

template<class Type>
class PhoenixSingleton
{
public:
	static Type& getInstance()
	{
		if (destroyed)
		{
			new(pInst) Type;
			atexit(killPhoenix);
			destroyed = false;
		}
		else if (pInst == 0)
		{
			create();
		}
		return *pInst;
	}

	static Type& getInstancePtr()
	{
		if (destroyed)
		{
			new(pInst) Type;
			atexit(killPhoenix);
			destroyed = false;
		}
		else if (pInst == 0)
		{
			create();
		}
		return pInst;
	}

 protected:
	PhoenixSingleton() {}
	PhoenixSingleton(const Type & other);
    ~PhoenixSingleton() {
      destroyed = true;  // 1)
    }

	static void create()
	{
	  static Type inst;
	  pInst = &inst;
	}

	static void killPhoenix() {
	  pInst->~Type();
	}

    static bool destroyed;
    static Type* pInst;
};

template<class Type>
bool PhoenixSingleton<Type>::destroyed = false;

template<class Type>
Type* PhoenixSingleton<Type>::pInst = 0;

} /*Util*/ } /*Framework*/

#endif /* FRAMEWORK_PHOENIXSINGLETON_H_ */
